from __future__ import annotations

from functools import lru_cache
from pathlib import Path
from typing import Literal

from pydantic_settings import BaseSettings, SettingsConfigDict

BASE_DIR = Path(__file__).resolve().parent.parent.parent


class Settings(BaseSettings):
  model_config = SettingsConfigDict(
    env_file=BASE_DIR / '.env',
    env_file_encoding='utf-8',
    case_sensitive=False,
  )

  app_name: str = 'Love Notes API'
  environment: Literal['local', 'staging', 'production'] = 'local'
  debug: bool = False
  api_v1_prefix: str = '/api/v1'
  docs_url: str | None = '/docs'
  openapi_url: str | None = '/openapi.json'
  # Base site URL for links in emails, e.g., https://app.example.com
  site_base_url: str | None = None

  mysql_user: str = 'love'
  mysql_password: str = 'love_pass'
  mysql_host: str = 'localhost'
  mysql_port: int = 3306
  mysql_db: str = 'love_notes'
  mysql_async_driver: Literal['asyncmy', 'aiomysql'] = 'asyncmy'

  redis_url: str = 'redis://localhost:6379/0'

  jwt_secret_key: str = 'change_me'
  jwt_refresh_secret_key: str = 'change_me_refresh'
  access_token_expire_minutes: int = 30
  refresh_token_expire_minutes: int = 60 * 24 * 14
  algorithm: str = 'HS256'

  smtp_host: str | None = None
  smtp_port: int = 465
  smtp_username: str | None = None
  smtp_password: str | None = None
  smtp_use_tls: bool = True
  email_sender: str | None = None

  ai_provider: Literal['openai', 'deepseek', 'dashscope'] = 'openai'
  openai_api_key: str | None = None
  langchain_model: str = 'gpt-4o-mini'
  langchain_temperature: float = 0.7
  deepseek_api_key: str | None = None
  deepseek_api_base: str = 'https://api.deepseek.com/v1'
  dashscope_api_key: str | None = None
  dashscope_model: str = 'qwen-plus'

  # External integrations
  brave_api_key: str | None = None
  serpapi_key: str | None = None
  amap_web_key: str | None = None

  # Agent referent lifetime (pronoun -> partner)
  referent_lifetime_msgs: int = 5
  referent_lifetime_secs: int = 600

  # Optional outbound proxies for web access
  http_proxy: str | None = None
  https_proxy: str | None = None

  # Preferences extraction/config
  prefs_strict_relation: bool = False  # True: 不从用户级画像回退
  prefs_extract_window: int = 6       # 从最近 N 条消息中提取

  @property
  def mysql_async_url(self) -> str:
    return (
      f"mysql+{self.mysql_async_driver}://{self.mysql_user}:{self.mysql_password}"
      f"@{self.mysql_host}:{self.mysql_port}/{self.mysql_db}"
    )

  @property
  def mysql_sync_url(self) -> str:
    return (
      f"mysql+mysqlconnector://{self.mysql_user}:{self.mysql_password}"
      f"@{self.mysql_host}:{self.mysql_port}/{self.mysql_db}"
    )


@lru_cache
def get_settings() -> Settings:
  return Settings()


settings = get_settings()
